package com.fragrance.service.impl;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.iot.model.v20170420.QueryDeviceByNameResponse.DeviceInfo;
import com.fragrance.cfg.FragranceJFinalCfg;
import com.fragrance.model.DeviceMainModel;
import com.fragrance.model.UserDeviceBindModel;
import com.fragrance.model.UserDeviceModel;
import com.fragrance.service.DeviceMainService;
import com.fragrance.service.IotApiService;
import com.fragrance.service.IotRecvDataProcessService;
import com.fragrance.service.UserDeviceBindService;
import com.fragrance.util.Constants;
import com.jfinal.plugin.redis.Redis;

/**
 * 接收的数据处理
 * 
 * @author zhilin
 *
 */
public class IotRecvDataProcessServiceImpl implements IotRecvDataProcessService {

	private final static Logger logger = LoggerFactory.getLogger(IotRecvDataProcessServiceImpl.class);

	private DeviceMainService deviceService = new DeviceMainServiceImpl();
	
	private UserDeviceBindService userDeviceBindService = new UserDeviceBindServiceImpl();

	private final static SimpleDateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	private IotApiService iotApiService = new IotApiServiceImpl();

	/**
	 * 数据处理
	 * 
	 */
	@Override
	public void dataProcess(String data) {
		try {
			if (data.startsWith("AA")) {
				Map<String, Object> timeResult = new HashMap<String, Object>();
				// 返回全部数据
				String imei = data.substring(34, 42);
				String gear = data.substring(33, 34);// 档位
				String rightStatusGet = data.substring(2, 3);// 锁机状态，0允许使用，1代表锁机状态
				String openStatus = data.substring(3, 4);// 开关机状态，0代表关机，1代表开机状态（机器传入值）
				String dampness = data.substring(4, 6);// 湿度
				String temperature = data.substring(6, 8);// 温度
				String start_time1 = data.substring(9, 13); // 开机时间1
				logger.info("--- 打印获取的时间 ---- start_time1{}",start_time1);
				String close_time1 = data.substring(13, 17); // 关机时间1
				String start_time2 = data.substring(17, 21); // 开机时间2
				String close_time2 = data.substring(21, 25); // 关机时间2
				String start_time3 = data.substring(25, 29); // 开机时间3
				String close_time3 = data.substring(29, 33); // 关机时间3
				// 1、通过imei号获取该香氛机信息t_device_main
				List<DeviceMainModel> deviceMainModels = deviceService.findDevice(imei);
				if (deviceMainModels != null && deviceMainModels.size() == 1) {
					DeviceMainModel deviceMainModel = deviceMainModels.get(0);
					// 3、通过imei号在数据库里查询该设备是否已经被使用使用 表t_user_device
					UserDeviceModel userDeviceModel = deviceService.isOpen(imei);
					// userDeviceModel不为空，说明机器在使用，传入全部值，表示对机器进行调档功能
					if (userDeviceModel != null) {
						String redisValue = Redis.use("users").get(imei);
						logger.info("请在iotcfg.properties配置carla.iot.productKey");
						if(redisValue.equals("A")){
							// iotcfg.properties配置的productKey
							String productKey = FragranceJFinalCfg.iotcfgProp.get("carla.iot.productKey");
							if (StringUtils.isEmpty(productKey)) {
								logger.info("请在iotcfg.properties配置carla.iot.productKey");
							}
							// 在云端获取机器状态 是否在线
							String deviceName = deviceMainModel.getStr("imei");
							logger.info("productKey=" + productKey + ", deviceName=" + deviceName);
							DeviceInfo deviceInfo = iotApiService.queryDeviceByName(productKey, deviceName);
							if (deviceInfo == null || !Constants.DEV_ONLINE.equals(deviceInfo.getDeviceStatus())) {
								logger.info("设备状态不正确:" + JSON.toJSONString(deviceInfo));
							}
							// 组装发送数据
							SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
							String dateTime = dateFormat.format(new Date());
							String timeStd = dateTime.substring(11, 16);
							String time = timeStd.replaceAll(":", "");
							String setTimeMsg = "DY5T" + time;
							logger.info("校准的时间发送的数据：" + setTimeMsg);
							String topic = "/" + productKey + "/" + deviceName + "/get";
							// 该数据发送为异步发送，所以前端需要轮询
							String publishResult = iotApiService.publishMssage(productKey, topic, setTimeMsg);
							if (StringUtils.isNotEmpty(publishResult)) {
								// imei号
								String redisKey = deviceName;
								String msgId = publishResult;
								Redis.use("users").setex(redisKey, 60 * 10, msgId);
								// TODO 可以循环一段时间
							}
							logger.info("上送消息：" + setTimeMsg);
							String value = "B";
							Redis.use("users").setex(imei,24 * 60 * 60, value);
						}
						String openid = userDeviceModel.getStr("wx_open_id");
						if ("1".equals(openStatus)) {
							// 调档
							// 在表t_user_device更新一条记录 说明机器在用
							Map<String, Object> gearData = new HashMap<String, Object>();
							
							StringBuilder start1timeBuild = new StringBuilder();
							String start1_time1 = start1timeBuild.append(start_time1).insert(2, ":").toString(); // 开机时间1
							StringBuilder close1timeBuild = new StringBuilder();
							String close1_time1 = close1timeBuild.append(close_time1).insert(2, ":").toString(); // 关机时间1
							StringBuilder start2timeBuild = new StringBuilder();
							String start2_time2 = start2timeBuild.append(start_time2).insert(2, ":").toString(); // 开机时间2
							StringBuilder close2timeBuild = new StringBuilder();
							String close2_time2 = close2timeBuild.append(close_time2).insert(2, ":").toString(); // 关机时间2
							StringBuilder start3timeBuild = new StringBuilder();
							String start3_time3 = start3timeBuild.append(start_time3).insert(2, ":").toString(); // 开机时间3
							StringBuilder close3timeBuild = new StringBuilder();
							String close3_time3 = close3timeBuild.append(close_time3).insert(2, ":").toString(); // 关机时间3
							
							logger.info("--- 打印转换后的时间 ----start1_time1{}",start1_time1);
							//时间拼接
							SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
							SimpleDateFormat nowTime = new SimpleDateFormat("yyyy-MM-dd ");
							Date date = new Date();
							
							if(dateFormat.parse(nowTime.format(date)+start1_time1).before(dateFormat.parse(nowTime.format(date)+close1_time1))){
								
								gearData.put("work_start_time1", nowTime.format(date)+start1_time1);
								gearData.put("work_close_time1", nowTime.format(date)+close1_time1);
								logger.info("第一段时间-----work_start_time1",nowTime.format(date)+start1_time1);
								logger.info("第一段时间-----work_close_time1",nowTime.format(date)+close1_time1);
							}else if(dateFormat.parse(nowTime.format(date)+close1_time1).before(dateFormat.parse(nowTime.format(date)+start1_time1))){
								
								Calendar calendar = new GregorianCalendar();
								calendar.setTime(date);
								calendar.add(calendar.DATE,1);//把日期往后增加一天.整数往后推,负数往前移动
								date=calendar.getTime(); //这个时间就是日期往后推一天的结果 
								gearData.put("work_start_time1", nowTime.format(new Date())+start1_time1);
								gearData.put("work_close_time1", nowTime.format(date)+close1_time1);
								
							}
							
							if (dateFormat.parse(nowTime.format(date) + start2_time2).before(dateFormat.parse(nowTime.format(date) + close2_time2))) {

								gearData.put("work_start_time2", nowTime.format(date) + start2_time2);
								gearData.put("work_close_time2", nowTime.format(date) + close2_time2);

							} else if (dateFormat.parse(nowTime.format(date) + close2_time2).before(dateFormat.parse(nowTime.format(date) + start2_time2))) {

								Calendar calendar = new GregorianCalendar();
								calendar.setTime(date);
								calendar.add(calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动
								date = calendar.getTime(); // 这个时间就是日期往后推一天的结果
								gearData.put("work_start_time2", nowTime.format(new Date()) + start2_time2);
								gearData.put("work_close_time2", nowTime.format(date) + close2_time2);

							}
							
							if (dateFormat.parse(nowTime.format(date) + start3_time3).before(dateFormat.parse(nowTime.format(date) + close3_time3))) {

								gearData.put("work_start_time3", nowTime.format(date) + start3_time3);
								gearData.put("work_close_time3", nowTime.format(date) + close3_time3);

							} else if (dateFormat.parse(nowTime.format(date) + close3_time3).before(dateFormat.parse(nowTime.format(new Date()) + start3_time3))) {

								Calendar calendar = new GregorianCalendar();
								calendar.setTime(date);
								calendar.add(calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动
								date = calendar.getTime(); // 这个时间就是日期往后推一天的结果
								gearData.put("work_start_time3", nowTime.format(new Date()) + start3_time3);
								gearData.put("work_close_time3", nowTime.format(date) + close3_time3);

							}
							
							gearData.put("wx_open_id", openid);
							gearData.put("imei", deviceMainModel.getStr("imei"));
							gearData.put("sim_no", deviceMainModel.getStr("sim_no"));
							gearData.put("gear", gear);
							// 更新用户使用设备情况
							boolean flag = deviceService.updateUserDeviceGear(gearData);
							logger.info("^^手动调档到" + gear + "成功^^" + flag);
						} else {
							logger.info("未知状态");
						}
					} else {
						// 手动开机或者解锁后会走该分支
						if ("1".equals(openStatus)) {
							//先判断该机器是否被绑定，若绑定取绑定人的openid
							Map<String, String> opendData = new HashMap<String, String>();
							
							List<UserDeviceBindModel> userDeviceBindModels = userDeviceBindService.findBindDevice(imei);
							if (userDeviceBindModels != null && userDeviceBindModels.size() > 0) {
								logger.info("该设备已经被绑定imei = " + imei);
								UserDeviceBindModel deviceBindInfo = userDeviceBindModels.get(0);
								String openid = deviceBindInfo.getStr("wx_open_id");
								opendData.put("wx_open_id", openid);
							}else{
								opendData.put("wx_open_id", imei);
							}
							// 机器传进来的1 代表开机状态 ，在表t_user_device插入一条记录，说明该机器已经被开机
							opendData.put("imei", deviceMainModel.getStr("imei"));
							opendData.put("sim_no", deviceMainModel.getStr("sim_no"));
							opendData.put("dampness", dampness);
							opendData.put("temperature", temperature);
							opendData.put("gear", gear);
							opendData.put("device_status", String.valueOf(0));
							// 更新设备再使用
							boolean flag = deviceService.addUserDevice(opendData);
							// 1关机
							Integer oldDeviceStatus = 1;
							// 0开机
							Integer newDeviceStatus = 0;
							// 更新用户使用设备情况 机器状态：0代表开机，1代表关机
							flag = deviceService.updateStatus(newDeviceStatus, imei, oldDeviceStatus);
							logger.info("@@@手动开机成功@@@" + flag);
							if(flag){
								
								// iotcfg.properties配置的productKey
								String productKey = FragranceJFinalCfg.iotcfgProp.get("carla.iot.productKey");
								if (StringUtils.isEmpty(productKey)) {
									logger.info("请在iotcfg.properties配置carla.iot.productKey");
								}
								// 在云端获取机器状态 是否在线
								String deviceName = deviceMainModel.getStr("imei");
								logger.info("productKey=" + productKey + ", deviceName=" + deviceName);
								DeviceInfo deviceInfo = iotApiService.queryDeviceByName(productKey, deviceName);
								if (deviceInfo == null || !Constants.DEV_ONLINE.equals(deviceInfo.getDeviceStatus())) {
									logger.info("设备状态不正确:" + JSON.toJSONString(deviceInfo));
								}
								// 组装发送数据
								SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
								String dateTime = dateFormat.format(new Date());
								String timeStd = dateTime.substring(11, 16);
								String time = timeStd.replaceAll(":", "");
								String setTimeMsg = "DY5T" + time;
								logger.info("校准的时间发送的数据：" + setTimeMsg);
								String topic = "/" + productKey + "/" + deviceName + "/get";
								// 该数据发送为异步发送，所以前端需要轮询
								String publishResult = iotApiService.publishMssage(productKey, topic, setTimeMsg);
								if (StringUtils.isNotEmpty(publishResult)) {
									// imei号
									String redisKey = deviceName;
									String msgId = publishResult;
									Redis.use("users").setex(redisKey, 60 * 10, msgId);
									// TODO 可以循环一段时间
								}
								logger.info("上送消息：" + setTimeMsg);
								String value = "A";
								Redis.use("users").setex(imei,24 * 60 * 60, value);
									
							}
						} else {
							logger.info("没有查到用户在用的设备openStatus=" + openStatus);
						}
					}
				} else {
					// TODO

				}
			} else if (data.startsWith("41AT")) {
				// 锁机
				logger.info("@@@锁机成功@@@");
			} else if (data.startsWith("10AT")) {
				// 手动关机 小程序关机
				logger.info("$$$进入关机$$$");
				// 关机
				// 修改数据库的device_status状态为关机
				Map<String, String> closeDate = new HashMap<String, String>();
				String imei = data.substring(27, 35);
				logger.info("$$$关机分支$$$" + imei);
				closeDate.put("imei", imei);
				// 1、获取香氛机信息t_device_main
				List<DeviceMainModel> deviceMainModels = deviceService.findDevice(imei);
				logger.info("$$$关机分支$$$" + deviceMainModels);
				if (deviceMainModels != null && deviceMainModels.size() == 1) {
					DeviceMainModel deviceMainModel = deviceMainModels.get(0);
					// 3、在数据库里查询设备是否已经有人使用 表t_user_device
					UserDeviceModel userDeviceModel = deviceService.isOpen(imei);
					// userDeviceModel不为空说明机器在使用状态
					if (userDeviceModel != null) {
						String openid = userDeviceModel.getStr("wx_open_id");
						closeDate.put("wx_open_id", openid);
						closeDate.put("imei", deviceMainModel.getStr("imei"));
						closeDate.put("sim_no", deviceMainModel.getStr("sim_no"));
						// 不再使用设备
						closeDate.put("device_status", String.valueOf(1));
						Date date = new Date();
						closeDate.put("close_time", FORMAT.format(date));
						boolean flag = deviceService.updateUserDevice(closeDate);
						logger.info("**手动关机成功-1**" + flag);
						// 0开机
						Integer oldDeviceStatus = 0;
						// 1关机
						Integer newDeviceStatus = 1;
						flag = deviceService.updateStatus(newDeviceStatus, imei, oldDeviceStatus);
						logger.info("**手动关机成功-2**" + flag);
						Redis.use("users").del(imei);
					} else {
						// TODO

					}
				} else {
					// TODO

				}
			} else if (data.startsWith("21") || //
					data.startsWith("22") || //
					data.startsWith("23") || //
					data.startsWith("24") || //
					data.startsWith("25") || //
					data.startsWith("26")) {
				// 小程序调档成功
				logger.info("^^^小程序调档成功^^^");
			} else if (data.startsWith("OK")) {
				// 小程序定时成功
				logger.info("***小程序定时成功***");
				
			}else if (data.startsWith("5T")) {
				// 小程序校验时间成功
				logger.info("***小程校验时间成功***");
				
			}else{
				logger.info("***传入值不符合要求***");
				
			}
			
		} catch (Exception e) {
			logger.info("***手动操作机器异常***",e);
		}

	}

}
